package com.dream.app.controller;

import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.dream.app.cache.AppCodeCache;
import com.dream.app.cache.AppOrgCache;
import com.dream.app.service.OrgService;
import com.dream.base.controller.BaseController;
import com.dream.master.service.ProductCategoryService;
import com.dream.master.service.ProductService;
import com.dream.model.app.AppCodeItem;
import com.dream.model.app.AppOrg;
import com.dream.model.master.Product;
import com.dream.model.master.ProductCategory;
import com.dream.model.master.ProductPart;
import com.dream.utils.annotation.AccessLog;
import com.dream.utils.annotation.SkipAuthority;
import com.dream.utils.hibernate.PagingVO;
import com.dream.utils.log.DreamLogUtils;
import com.dream.vo.app.AppCodeConstants;
import com.dream.vo.base.FirstGroup;
import com.dream.vo.base.MvcValidtorResult;
import com.dream.vo.base.ResultType;
import com.dream.vo.base.TreeNodeVO;
import com.dream.vo.master.ProductPartVO;
import com.dream.vo.master.ProductVO;
import com.google.common.collect.Maps;

/**
 * @copyright evan
 * @author evan
 * @Revision
 * @date 2013/9/29
 */
@Controller
@RequestMapping(value = "/mst")
public class MasterController extends BaseController{
	
	@Autowired
	private ProductCategoryService productCategoryService;
	
	@Autowired
	private ProductService productService;
	
	@Autowired
	private AppCodeCache appCodeCache;
	
	@Autowired
	private AppOrgCache orgCache;
	
	@Autowired
	private OrgService orgService;
	
	
	@RequestMapping(value = "/pro/cat/view")
	@SkipAuthority
	@ResponseBody
	@AccessLog(module="master",content="产品分类")
	public ProductCategory overView(Model model,Long id) {

		ProductCategory root = productCategoryService.getCategory(id);
		return root;
		
	}
	
	@RequestMapping(value = "/pro/cat/children")
	@SkipAuthority
	@AccessLog(module="master",content="产品分类")
	public String showChildren(Model model, Long parentId) {

		model.addAttribute("parent", productCategoryService.getChildrens(parentId));

		return "base/tree_node_detail";
	}
	
	@ResponseBody
	@RequestMapping(value = "/pro/cat/update")
	@AccessLog(module="master",content="产品分类更新")
	@SkipAuthority
	public Map<String,Object> categoryItemUpdate(Model modelMap,TreeNodeVO vo) {
		
		Map<String, Object> result = Maps.newHashMap();	
		try{
			productCategoryService.updateCategory(vo, getUser());
			result.put(RESULT_TYPE,ResultType.SUCCESS.toInteger());
		}catch(Exception ex){
				result.put(RESULT_TYPE, ResultType.EXCEPTION.toInteger());
				DreamLogUtils.error(this,"appCodeItemUpdate","modify app code occured exception", ex);
		}
			
		return result;
	}
	
	@ResponseBody
	@RequestMapping(value = "/pro/cat/delete/{id}")
	@AccessLog(module="master",content="删除产品分类")
	@SkipAuthority
	public  Map<String, Object> categoryItemDelete(@PathVariable long id) {
		
		Map<String,Object> result = Maps.newHashMap();
		try {
			productCategoryService.deleteCategory(id, getUser());
			result.put(RESULT_TYPE, ResultType.SUCCESS.toInteger());
		} catch (Exception ex) {
			result.put(RESULT_TYPE,ResultType.ERROR.toInteger());
			DreamLogUtils.error(this, "codeItemDelete","delete code item occured exception", ex);
		}
		return result;
	}
	
	@RequestMapping(value = "/pro/cat/children/item")
	@SkipAuthority
	@AccessLog(module="master",content="产品分类列表")
	public String showChildrenItems(Model model, Long parentId) {
		
		ProductCategory childrens = productCategoryService.getChildrens(parentId);
		model.addAttribute("options", childrens==null ? null : childrens.getChildren());
		return "base/select_options";
	}
	
	@RequestMapping(value = "/pro/list")
	@SkipAuthority
	@AccessLog(module="master",content="产品列表")
	public String productList(Model model,ProductVO vo,PagingVO page) {
		
		PagingVO pageVO = productService.query(vo, page);
		model.addAttribute("pageVO", pageVO);
		return "master/product/data/product_list_data";
	}
	
	@RequestMapping(value = "/pro/list/init")
	@SkipAuthority
	public String productListInit(Model modelMap) {
		
		ProductCategory childrens = productCategoryService.getChildrens(null);
		modelMap.addAttribute("firstCats", childrens==null ? null : childrens.getChildren());
		return "pro_list";
		
	}
	
	@RequestMapping(value = "/pro/update/init")
	@SkipAuthority
	public String productUpdateInit(Model modelMap,String productId) {
		
		Product product = null;
		if(StringUtils.isNotBlank(productId)) {
			product = productService.queryById(productId);
		}
		modelMap.addAttribute("product", product);
		modelMap.addAttribute("isNew", StringUtils.isBlank(productId));
		ProductCategory childrens = productCategoryService.getChildrens(null);
		modelMap.addAttribute("firstCats", childrens==null ? null : childrens.getChildren());
		return "pro_update";
		
	}
	
	@ResponseBody
	@RequestMapping(value = "/pro/update")
	@AccessLog(module="master",content="产品更新")
	@SkipAuthority
	public Map<String,Object> productUpdate(Model modelMap,@Validated({FirstGroup.class}) ProductVO vo,BindingResult valResult) {
		
		Map<String,Object> result = Maps.newHashMap();
		MvcValidtorResult errors = populateErrors(valResult);
		
		if(errors.hasErrors()){
			result.put(RESULT_TYPE, ResultType.INPUT.toInteger());
			result.put(RESULT_CONTENT, errors);
			
		}else{
			try{
				if(StringUtils.isBlank(vo.getId()) && StringUtils.isBlank(vo.getSecondCat())){
					this.addFieldMessage(errors, "secondCat", "err0001");
				}else{
					productService.update(vo, getUser());
					result.put(RESULT_TYPE,ResultType.SUCCESS.toInteger());
				}
			}catch(Exception ex){
					result.put(RESULT_TYPE, ResultType.EXCEPTION.toInteger());
					DreamLogUtils.error(this,"productUpdate","update product code occured exception", ex);
			}
		}
		return result;
	}
	
	@ResponseBody
	@RequestMapping(value = "/pro/delete/{id}")
	@AccessLog(module="master",content="删除产品分类")
	@SkipAuthority
	public  Map<String, Object> productDelete(@PathVariable String id) {
		
		Map<String,Object> result = Maps.newHashMap();
		try {
			productService.delete(id, getUser());
			result.put(RESULT_TYPE, ResultType.SUCCESS.toInteger());
		} catch (Exception ex) {
			result.put(RESULT_TYPE,ResultType.ERROR.toInteger());
			DreamLogUtils.error(this, "productDelete","product code item occured exception", ex);
		}
		return result;
	}
	
	@RequestMapping(value = "/pro/part/list")
	@SkipAuthority
	@AccessLog(module="master",content="产品列表")
	public String productPartList(Model model,ProductPartVO vo,PagingVO page) {
		
		model.addAttribute("pageVO",productService.queryPart(vo, page));
		return "master/product/data/product_part_list_data";
	}
	
	@RequestMapping(value = "/pro/part/list/init")
	@SkipAuthority
	@AccessLog(module="master",content="产品列表")
	public String productPartListInit(Model modelMap) {
		
		List<AppCodeItem> levels = appCodeCache.getByAppCodeName(AppCodeConstants.PRO_PART_LEVEL);
		List<AppCodeItem> types = appCodeCache.getByAppCodeName(AppCodeConstants.PRO_PART_MAKE_TYPE);
		modelMap.addAttribute("partLevels",levels);
		modelMap.addAttribute("makeTypes",types);
		
		return "pro_part_list";
		
	}
	
	@RequestMapping(value = "/pro/part/update/init")
	@SkipAuthority
	public String productPartUpdateInit(Model modelMap,String id) {
		
		ProductPart part = new ProductPart();
		if(StringUtils.isNotBlank(id)) {
			part = productService.queryPartById(id);
		}
		modelMap.addAttribute("part", part);
		modelMap.addAttribute("isNew", StringUtils.isBlank(id));
		
		List<AppCodeItem> levels = appCodeCache.getByAppCodeName(AppCodeConstants.PRO_PART_LEVEL);
		List<AppCodeItem> types = appCodeCache.getByAppCodeName(AppCodeConstants.PRO_PART_MAKE_TYPE);
		modelMap.addAttribute("partLevels",levels);
		modelMap.addAttribute("makeTypes",types);
		
		return "pro_part_update";
		
	}
	
	@ResponseBody
	@RequestMapping(value = "/pro/part/update")
	@AccessLog(module="master",content="产品更新")
	@SkipAuthority
	public Map<String,Object> productPartUpdate(Model modelMap,@Validated({FirstGroup.class}) ProductPartVO vo,BindingResult valResult) {
		
		Map<String,Object> result = Maps.newHashMap();
		MvcValidtorResult errors = populateErrors(valResult);
		
		if(valResult.hasErrors()){
			result.put(RESULT_TYPE, ResultType.INPUT.toInteger());
			result.put(RESULT_CONTENT, errors);
			
		}else{
			try{
				productService.updatePart(vo, getUser());
				result.put(RESULT_TYPE,ResultType.SUCCESS.toInteger());
				
			}catch(Exception ex){
				
					result.put(RESULT_TYPE, ResultType.EXCEPTION.toInteger());
					DreamLogUtils.error(this,"productPartUpdate","update product part occured exception", ex);
			}
		}
		return result;
	}
	
	@ResponseBody
	@RequestMapping(value = "/pro/part/delete/{id}")
	@AccessLog(module="master",content="删除产品分类")
	@SkipAuthority
	public  Map<String, Object> productPartDelete(@PathVariable String id) {
		
		Map<String,Object> result = Maps.newHashMap();
		try {
			productService.deletePart(id, getUser());
			result.put(RESULT_TYPE, ResultType.SUCCESS.toInteger());
		} catch (Exception ex) {
			result.put(RESULT_TYPE,ResultType.ERROR.toInteger());
			DreamLogUtils.error(this, "productPartDelete","product part delete occured exception", ex);
		}
		return result;
	}
	
	@ResponseBody
	@RequestMapping(value = "/org/view")
	@SkipAuthority
	@AccessLog(module="app",content="部门结构")
	public AppOrg orgOverView(Model model,Long id) {
		
		AppOrg root = orgCache.getRoot();
		return root;
		
	}
	
	@RequestMapping(value = "/org/children")
	@SkipAuthority
	@AccessLog(module="app",content="部门结构子类")
	public String showOrgChildren(Model model, Long parentId) {
		
		if(parentId == null || parentId.compareTo(0L) < 0){
			parentId = orgCache.getRoot().getId();
		}
		
		AppOrg org = orgCache.getOrg(parentId);
		if(org != null){
			org.setChildren(orgCache.getChildren(parentId));
		}
		model.addAttribute("parent", org);
		return "base/tree_node_detail";
	}
	
	@ResponseBody
	@RequestMapping(value = "/org/update")
	@AccessLog(module="app",content="组织更新")
	@SkipAuthority
	public Map<String,Object> orgItemUpdate(Model modelMap,TreeNodeVO vo) {
		
		Map<String, Object> result = Maps.newHashMap();	
		try{
			orgService.update(vo, getUser());
			result.put(RESULT_TYPE,ResultType.SUCCESS.toInteger());
		}catch(Exception ex){
				result.put(RESULT_TYPE, ResultType.EXCEPTION.toInteger());
				DreamLogUtils.error(this,"deptItemUpdate","modify dept occured exception", ex);
		}
			
		return result;
	}
	
	@ResponseBody
	@RequestMapping(value = "/org/delete/{id}")
	@AccessLog(module="app",content="删除部门")
	@SkipAuthority
	public  Map<String, Object> orgItemDelete(@PathVariable long id) {
		
		Map<String,Object> result = Maps.newHashMap();
		try {
			orgService.delete(id, getUser());
			result.put(RESULT_TYPE, ResultType.SUCCESS.toInteger());
		} catch (Exception ex) {
			result.put(RESULT_TYPE,ResultType.ERROR.toInteger());
			DreamLogUtils.error(this, "deptItemDelete","delete dept item occured exception", ex);
		}
		return result;
	}
	
	@RequestMapping(value = "/org/children/item")
	@SkipAuthority
	@AccessLog(module="master",content="组织结构")
	public String showOrgChildrenItems(Model model, Long parentId,Boolean isAll) {
		
		
		List<AppOrg> children = orgService.getChildrenOfMine(parentId,this.getUser()); 
		if(Boolean.TRUE.equals(isAll))
			children = orgCache.getChildren(parentId);
		
		model.addAttribute("options",children);
		return "base/select_options";
	}
	
	
}
